package com.quartz.monitor4job.controller;

import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.quartz.monitor4job.model.QuartzJob;
import com.quartz.monitor4job.model.QuartzLog;
import com.quartz.monitor4job.service.QuartzLogService;
import com.quartz.monitor4job.service.QuartzService;
import com.quartz.monitor4job.util.ThreadUtilities;

/**
 * quartz监控控制器
 * 
 * @author LIPENG
 *
 * @date 2017年6月7日 下午6:41:05
 *
 * @version V1.0
 */
@Controller
@RequestMapping(value = "/quartzListener", method = {RequestMethod.POST, RequestMethod.GET})
public class QuartzController extends BaseController{
	private static final Logger logger = LoggerFactory.getLogger(QuartzController.class);
	@Autowired
	private SchedulerFactoryBean quartzScheduler;
	
	@Autowired
	private QuartzService quartzService;
	
	@Autowired
	private QuartzLogService quartzLogService;

	@RequestMapping("/listJobs")
	@ResponseBody
	public String listJobs(HttpServletRequest request, HttpServletResponse response) {
		List<QuartzJob> list = new ArrayList<QuartzJob>();
		try {
			QuartzJob quartzJob=new QuartzJob();
			quartzJob.setSchedName(quartzScheduler.getScheduler().getSchedulerName());
			list=quartzService.listJobs(quartzJob);
			return generateHtml("vm/listJobs.vm", list);
		} catch (Exception e) {
			logger.error("查询jobs列表出错", e);
		}
		return JSON.toJSONString(list);
	}

	@RequestMapping("/runJob")
	@ResponseBody
	public String runJob(HttpServletRequest request, HttpServletResponse response) {
		String jobName=request.getParameter("jobName");
		logger.info("执行选择的Job对象 doRunQuartzJob runName:" + jobName);
		try {
			Scheduler scheduler = quartzScheduler.getScheduler();
			if (StringUtils.isNotBlank(jobName) && scheduler.checkExists(JobKey.jobKey(jobName))) {
				JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(jobName));
				// 重复执行的次数，因为加入任务的时候马上执行了，所以不需要重复，否则会多一次。
				Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test-" + jobName, Scheduler.DEFAULT_GROUP).startNow()
						.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).withRepeatCount(0)).forJob(jobDetail)
						.build();
				if(scheduler.checkExists(trigger.getKey())){
					scheduler.pauseTrigger(trigger.getKey());
					scheduler.unscheduleJob(trigger.getKey());
				}
				scheduler.scheduleJob(trigger);
			}
			response.sendRedirect("listJobs.do");
			return listJobs(request, response);
		} catch (Exception e) {
			logger.error("doRunQuartzJob 执行选择的Job对象出错", e);
			return "fail";
		}
	}
	
	@RequestMapping("/queryQuartzLog")
	@ResponseBody
	public String queryQuartzLog(HttpServletRequest request, HttpServletResponse response) {
		logger.info("执行选择的Job对象 queryQuartzLog quartzLog:");
		try {
			Map<String,Object> result=new HashMap<String,Object>();
			QuartzJob quartzJob=new QuartzJob();
			quartzJob.setName(request.getParameter("jobName"));
			quartzJob.setSchedName(quartzScheduler.getScheduler().getSchedulerName());
			QuartzLog quartzlog=new QuartzLog();
			String pageNo=request.getParameter("pageNo");
			pageNo=pageNo==null?"1":pageNo;
			quartzlog.setPageNo(Integer.parseInt(pageNo));
			quartzlog.setJobName(request.getParameter("jobName"));
			List<QuartzLog> list=quartzLogService.list(quartzlog);
			result.put("list", list);
			result.put("params", quartzJob);
			result.put("jobDetail", quartzService.getJobDetail(quartzJob));
			return generateHtml("vm/queryQuartzLog.vm", result);
		} catch (Exception e) {
			logger.error("queryQuartzLog 执行选择的Job对象出错", e);
			return "fail";
		}
	}
	
	@RequestMapping("/getStackTrace")
	@ResponseBody
	public String getStackStace(HttpServletRequest request, HttpServletResponse response) {
		logger.info("执行选择的Job对象 queryQuartzLog quartzLog:");
		try {
			String threadId=request.getParameter("threadId");
			if(StringUtils.isBlank(threadId)){
				return "";
			}
			
		    ThreadInfo info = ThreadUtilities.getExtendThreadInfo(Long.valueOf(threadId));
		    List<String> list=new ArrayList<String>();
		    StackTraceElement[] st=info.getStackTrace();
		    int index=0;
		    MonitorInfo[] monitors=info.getLockedMonitors();
		    for(StackTraceElement e:st){ 
		    	StringBuffer sb=new StringBuffer();
		        if(index>0){  
		        	sb.append(" <- ");  
		        	sb.append(System.getProperty("line.separator"));  
		        }  
		        sb.append(e.toString()+ "\n");
		        list.add(sb.toString());
		        if (monitors != null) {
					for (MonitorInfo mi : monitors) {
						if (mi.getLockedStackDepth() == index) {
							list.add(" <- -     locked   "+mi.toString());
						}
					}
				}
				index++;
		    }  
			return generateHtml("vm/getStackTrace.vm", list);
		} catch (Exception e) {
			logger.error("doRunQuartzJob 执行选择的Job对象出错", e);
			return "fail";
		}
	}
	
	
	
}
